package fun.werfamily.wf.base.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import fun.werfamily.wf.base.dto.BaseUserInfoDTO;
import fun.werfamily.wf.base.enums.CommonResponseEnum;
import fun.werfamily.wf.base.exception.BaseCoreException;
import io.jsonwebtoken.*;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @Author: Mr.WenMing Zhang
 * @Date: 2022/07/29 17:47
 * @Description:
 **/
@Component
@Slf4j
public class TokenUtil {
    private static final String TOKEN_KEY = "wf_family";
    private static final String AUTH_HEADER = "Authorization";

    private static final String TOKEN_PREFIX_REGEX = "^[B|b][E|e][A|a][R|r][E|e][R|r] .*";

    private static final String TOKEN_PREFIX = "Bearer ";

    public static String genToken(String userId, String userName, String userCode) {
        JSONObject subject = new JSONObject(true);
        subject.put("userId", userId);
        subject.put("userName", userName);
        subject.put("userCode", userCode);
        //创建JWT对象
        JwtBuilder jwtBuilder = Jwts.builder()
                .setId(userId)
                .setSubject(subject.toJSONString())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + 7 * 24 * 60 * 60 * 1000))
                .signWith(SignatureAlgorithm.HS256, TOKEN_KEY);
        //得到token
        String token = jwtBuilder.compact();
        log.info("token{}", token);
        return TOKEN_PREFIX + token;
    }


    public static BaseUserInfoDTO parseToken(HttpServletRequest request) {
        String token = validateToken(request);
        BaseUserInfoDTO baseUserInfoDTO = new BaseUserInfoDTO();
        try {
            Claims claims = Jwts.parser().setSigningKey(TOKEN_KEY).parseClaimsJws(token).getBody();
            log.debug("id:" + claims.getId());
            log.debug("subject:" + claims.getSubject());
            log.debug("time:" + claims.getIssuedAt());
            baseUserInfoDTO = JSON.parseObject(claims.getSubject(), BaseUserInfoDTO.class);
        } catch (ExpiredJwtException exception) {
            log.error("token{}已过期", token);

        }
        return baseUserInfoDTO;
    }

    public static String validateToken(HttpServletRequest request) {
        String authHeader = request.getHeader(AUTH_HEADER);
        if (StringUtils.isBlank(authHeader)) {
            log.info("【JWT TOKEN】token为空,需要登录,token:{}", authHeader);
            throw new BaseCoreException(CommonResponseEnum.TOKEN_IS_EMPTY);
        }
        if (!authHeader.matches(TOKEN_PREFIX_REGEX)) {
            log.info("【JWT TOKEN】token 缺少bearer前缀信息");
            throw new BaseCoreException(CommonResponseEnum.TOKEN_IS_INVALID);
        }
        return extractJwtTokenFromAuthorizationHeader(authHeader);
    }
    public static String extractJwtTokenFromAuthorizationHeader(String auth) {
        //Replacing "Bearer Token" to "Token" directly
        return auth.replaceFirst("[B|b][E|e][A|a][R|r][E|e][R|r] ", "").replace(" ", "");
    }
}
